class Scopes {
    static scopes = [{}]
    static scopeStart = () => {
        Scopes.scopes.push({})
    }

    static scopeEnd = () => {
        Scopes.scopes.pop()
    }

    static valueOf = (name) => {
        for (let i = Scopes.scopes.length - 1; i >= 0; i--) {
            let scope = Scopes.scopes[i]
            if (Object.keys(scope).includes(name)) {
                return JSON.parse(JSON.stringify(scope[name]))
            }

        }
    }

    static define = (name, value) => {
        let scope = Scopes.scopes[Scopes.scopes.length - 1]
        scope[name] = value
    }
}

const valueOf = (name) => {
    return Scopes.valueOf(name)
}
const interpretExpressionBinary = (s) => {
    const mapper = {
        '+': (a, b) => a + b,
        '-': (a, b) => a - b,
        '*': (a, b) => a * b,
        '/': (a, b) => a / b,
        '>': (a, b) => a > b,
        '<': (a, b) => a < b,
        '==': (a, b) => a === b,
    }
    let lType = s.left.type
    let rType = s.right.type

    let lValue = null
    let rValue = null

    if(lType === TokenType.number){
        lValue = s.left.value
    }else if(lType === AstType.ExpressionBinary){
        lValue = interpretExpressionBinary(s.left)
    }else {
        log("left 的类型是", lType)
    }

    if (rType === TokenType.number) {
        rValue = s.right.value
    } else if (rType === AstType.ExpressionBinary) {
        rValue = interpretExpressionBinary(s.right)
    } else {
        log("rType 的类型是", rType)
    }

    let fun = mapper[s.operator.value]
    return fun(lValue, rValue)
}
const interpretExpression = (s) => {
    if (s.type === AstType.ExpressionBinary) {
        return interpretExpressionBinary(s)
    } else if (s.type === TokenType.number  || s.type === TokenType.string) {
        return s.value
    }
}
const interpretVariable = (s) => {
    let variable = null

    let value = interpretExpression(s.value)
    if(s.variable.type === TokenType.variable){
        variable = s.variable.value
    }else{
        log('这不是变量定义')
    }




    Scopes.define(variable, value)
}

const interpret  = (ast) => {
    log("ast", ast)
    for (const s of ast) {
        let type = s.type
        if(type === AstType.ExpressionBinary){
            return interpretExpression(s)
        } else if (type === AstType.DeclarationVariable) {
            interpretVariable(s)
        }
    }

}


